home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
IRIX 6.2 Applications 1996 May
/
SGI IRIX 6.2 Applications 1996 May.iso
/
dist
/
impr_dev.idb
/
usr
/
impressario
/
src
/
libspool
/
SLMain.c.z
/
SLMain.c
Wrap
C/C++ Source or Header
|
1996-05-06
|
46KB
|
1,536 lines
/**************************************************************************
* *
* Copyright (c) 1991 Silicon Graphics, Inc. *
* All Rights Reserved *
* *
* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SGI *
* *
* The copyright notice above does not evidence any actual of intended *
* publication of such source code, and is an unpublished work by Silicon *
* Graphics, Inc. This material contains CONFIDENTIAL INFORMATION that is *
* the property of Silicon Graphics, Inc. Any use, duplication or *
* disclosure not specifically authorized by Silicon Graphics is strictly *
* prohibited. *
* *
* RESTRICTED RIGHTS LEGEND: *
* *
* Use, duplication or disclosure by the Government is subject to *
* restrictions as set forth in subdivision (c)(1)(ii) of the Rights in *
* Technical Data and Computer Software clause at DFARS 52.227-7013, *
* and/or in similar or successor clauses in the FAR, DOD or NASA FAR *
* Supplement. Unpublished - rights reserved under the Copyright Laws of *
* the United States. Contractor is SILICON GRAPHICS, INC., 2011 N. *
* Shoreline Blvd., Mountain View, CA 94039-7311 *
**************************************************************************
*
* File: SLMain.c
*
* Description: This file contains all public function definitions for
* libspool, the printer spooler API library. The public functions
* either perform the required processing directly, call local
* functions in this file or call spooling system specific functions
* in the the spooling files (eg. SLBsd.c, or SLSsysV.c).
*
**************************************************************************/
#ident "$Revision: 1.3 $"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <ctype.h>
#include <bstring.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#ifdef _SL_FASTPATH
#include <fastprint.h>
#endif /* _SL_FASTPATH */
#include "spoolI.h"
/* Possible spooling systems */
static SLSpoolerStruct pos_spooler_list[] = {
{ SL_SPOOLER_BSD,
_SLBsdFindSpooler,
_SLBsdGetPrinterList,
_SLBsdGetPrinterInfo,
_SLBsdGetDefPrinterName,
_SLBsdGetPrinterSettings,
_SLBsdSubmitJob,
_SLBsdCancelJob,
_SLBsdGetSpoolerState,
_SLBsdSetSpoolerState,
_SLBsdGetQueue,
#ifdef _SL_FASTPATH
_SLBsdSupportsFastJob,
#endif /* _SL_FASTPATH */
_SLBsdFindUserName,
},
{ SL_SPOOLER_SYSV,
_SLSysVFindSpooler,
_SLSysVGetPrinterList,
_SLSysVGetPrinterInfo,
_SLSysVGetDefPrinterName,
_SLSysVGetPrinterSettings,
_SLSysVSubmitJob,
_SLSysVCancelJob,
_SLSysVGetSpoolerState,
_SLSysVSetSpoolerState,
_SLSysVGetQueue,
#ifdef _SL_FASTPATH
_SLSysVSupportsFastJob,
#endif /* _SL_FASTPATH */
_SLSysVFindUserName,
},
{ 0, NULL },
};
/* Global variables */
int SLdebug; /* Run-time debugging info provided if != 0 */
long SLnet_timeout = SL_NET_TIMEOUT; /* Timeout for network ops. (sec.) */
/* Local variables */
static SLSpoolerStruct *def_sptr; /* Pointer to the def spooler */
static uint def_spooler = SL_SPOOLER_NONE; /* Default spooler */
static uint avail_spoolers = SL_SPOOLER_NONE; /* Available spoolers */
static SLPrintJob print_job; /* Print job info */
/* Local functions */
static int find_spoolers(unsigned int*);
static void init_job(SLPrintJob*);
static SLPrintJob* submit_job(SLJobSourceUnion*, const char*, int, int,
int, const char*, const char*);
static void sort_plist(SLPrinterStruct*, int);
/**************************************************************************
*
* Function: SLGetSpooler
*
* Description: Returns the default spooling system for the library. If
* the default is SL_SPOOLER_NONE, an attempt is made to determine
* if either the SYS V lpsched or BSD lpd daemons are running.
*
* Parameters:
* defaultp (O) - default spooler (one of SL_SPOOLER_NONE,
* SL_SPOOLER_BSD or SL_SPOOLER_SYSV)
* availablep (O) - Bit mask of available spooling systems.
*
* Return: 0 indicates successful execution. -1 indicates execution error,
* SLerrno is set.
*
**************************************************************************/
int SLGetSpooler(unsigned int *defaultp, unsigned int *availablep)
{
register SLSpoolerStruct *sptr;
/*
* If appears no spoolers are available make sure before
* reporting it
*/
if (avail_spoolers == SL_SPOOLER_NONE) {
if (find_spoolers(&avail_spoolers) < 0)
RETURN_ERROR(SL_ERR_FIND_SPOOLER)
}
*availablep = avail_spoolers;
/*
* If a spooler other than NONE is selected return that.
* Otherwise look in available spooler list and set def spooler
* from first available one in list.
*/
if (def_spooler == SL_SPOOLER_NONE) {
/*
* Try to set the prefered spooler first
*/
*defaultp = SL_SPOOLER_NONE;
if (avail_spoolers & SL_SPOOLER_PREF) {
*defaultp = SL_SPOOLER_PREF;
for (sptr = pos_spooler_list; sptr->find_spooler_func; sptr++) {
if (SL_SPOOLER_PREF == sptr->mask) {
def_sptr = sptr;
break;
}
}
} else {
for (sptr = pos_spooler_list; sptr->find_spooler_func; sptr++) {
if (avail_spoolers & sptr->mask) {
*defaultp = sptr->mask;
def_sptr = sptr;
break;
}
}
}
} else {
*defaultp = def_spooler;
}
return SL_NOERROR;
}
/**************************************************************************
*
* Function: SLSetSpooler
*
* Description: Sets the default spooling system for future libspool
* functions.
*
* Parameters:
* spooler (I) - spooling system to make default (eg. SL_SPOOLER_BSD).
*
* Return: 0 is returned if execution is successful. If an error has
* occurred, -1 is returned and SLerrno is set. Note that it is
* considered an error to request a spooling system that is not
* available. It is also an error to specify SL_SPOOLER_NONE.
*
**************************************************************************/
int SLSetSpooler(unsigned int spooler)
{
register SLSpoolerStruct *sptr;
/*
* Make sure a spooler has been specified
*/
if (spooler == SL_SPOOLER_NONE)
RETURN_ERROR(SL_ERR_SPOOLER_NONE);
/*
* If appears no spoolers are available make sure before
* reporting an error.
*/
if (avail_spoolers == SL_SPOOLER_NONE) {
if (find_spoolers(&avail_spoolers) < 0)
RETURN_ERROR(SL_ERR_FIND_SPOOLER);
if (avail_spoolers == SL_SPOOLER_NONE)
RETURN_ERROR(SL_ERR_NO_SPOOLERS);
}
/*
* Make sure specified spooler is in list of available spoolers
* and if so set the default spooler to the specified spooler.
*/
if (spooler & avail_spoolers) {
for (sptr = pos_spooler_list; sptr->find_spooler_func; sptr++) {
if (spooler & sptr->mask) {
def_spooler = spooler;
def_sptr = sptr;
break;
}
}
} else
RETURN_ERROR(SL_ERR_SPOOLER_UNKNOWN);
return SL_NOERROR;
}
/**************************************************************************
*
* Function: SLGetPrinterList
*
* Description: Provides a list of the printers recognized by the
* currently selected spooling system. Each time this function
* is called the old list pointer, if any, obtained from a
* previous call to this function becomes invalid. If the user
* wishes to preserve the old list, a copy must be made before
* calling this function.
*
* Parameters:
* printersp (O) - set to a list of available printers. If there
* are no printers registered with the spooler,
* this variable will be set to NULL.
* num_printersp (O) - number of available printers in list. If there
* are no printers available this value will be
* 0.
*
* Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
* error has occurred.
*
**************************************************************************/
int SLGetPrinterList(SLPrinterStruct *printersp[], int *num_printersp)
{
/*
* In case no spooler make sure sane values are sent back
*/
*printersp = NULL;
*num_printersp = 0;
/*
* Make sure we have a valid spooler selected
*/
CHECK_DEF_SPOOLER;
/*
* Call the appropriate function
*/
if (def_sptr->get_printers_func(printersp, num_printersp) < 0)
return SL_ERROR;
/*
* Sort the printer list by local name
*/
sort_plist(*printersp, *num_printersp);
return SL_NOERROR;
}
/**************************************************************************
*
* Function: SLGetPrinterInfo
*
* Description: Provides detailed information about the specified printer.
* Each time this function is called the old contents of the internal
* info structure become invalid. If the user wishes to preserve the
* old info, a copy must be made before calling this function.
*
* Parameters:
* printer (I) - printer whose info is wanted. If NULL,
* the default printer is used.
* printer_infop (O) - set to a printer information structure
* filled with information about the printer. Set
* to NULL if the specified printer does not exist.
*
* Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
* error has occurred. It is considered an error specifying a printer
* that is not available to the spooler.
*
**************************************************************************/
int SLGetPrinterInfo(const char *printer, SLPrinterStruct **printer_infop)
{
char *def_printer;
/*
* In case of error make sure sane values are sent back
*/
*printer_infop = NULL;
/*
* Make sure we have a valid spooler selected
*/
CHECK_DEF_SPOOLER;
/*
* Get the default printer name if no printer specified.
* Also sanity check the printer name, if specified.
*/
if (!printer) {
if (SLGetDefPrinterName(&def_printer) < 0)
return SL_ERROR;
printer = def_printer;
} else if (_SLIsEmpty(printer))
RETURN_ERROR(SL_ERR_BAD_PRINTER_NAME);
/*
* Call the appropriate function
*/
if (def_sptr->get_printer_info_func(printer, printer_infop) < 0)
return SL_ERROR;
return SL_NOERROR;
}
/**************************************************************************
*
* Function: SLGetDefPrinterName
*
* Description: Returns the name of the default printer for the currently
* selected spooliong system.
*
* Parameters:
* pnamep (O) - set to the name of the default printer or to
* NULL if no printer is registered as the default.
*
* Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
* error has occurred.
*
**************************************************************************/
int SLGetDefPrinterName(char **pnamep)
{
/*
* In case no spooler make sure sane values are sent back
*/
*pnamep = NULL;
/*
* Make sure we have a valid spooler selected
*/
CHECK_DEF_SPOOLER;
/*
* Call the appropriate function
*/
if (def_sptr->get_def_printer_func(pnamep) < 0)
return SL_ERROR;
return SL_NOERROR;
}
/**************************************************************************
*
* Function: SLGetPrinterSettings
*
* Description: Reads the spooler and printer option settings that have
* been saved by the SL settings save functions (e.g.
* SLSysVSaveSpoolerOptions and SLSysVSavePrinterOptions).
* The settings are returned in a spooling system independ format.
* Each time this function is called the old contents of the internal
* settings structure becomes invalid. If the caller wishes to
* preserve the old settings information, a copy must be made before
* calling this function.
*
* Note that calling this function does not effect the contents of
* the settings files stored on disk. If settings files for the
* specified printer are not found, default settings appropriate to
* the default behavior of the current spooler are returned.
*
* Parameters:
* printer (I) - printer whose settings are wanted. If NULL,
* the default printer is used. If the printer
* specified does not exist, the default settings
* for the current spooler will be returned.
* settingsp (O) - set to a printer settings structure
* filled with the currently saved spooler
* and printer option settings.
*
* Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
* error has occurred.
*
**************************************************************************/
int SLGetPrinterSettings(const char *printer, SLSettingsStruct **settingsp)
{
char *def_printer;
/*
* In case of error make sure sane values are sent back
*/
*settingsp = NULL;
/*
* Make sure we have a valid spooler selected
*/
CHECK_DEF_SPOOLER;
/*
* Get the default printer name if no printer specified.
* Also sanity check the printer name, if specified.
*/
if (!printer) {
if (SLGetDefPrinterName(&def_printer) < 0)
return SL_ERROR;
printer = def_printer;
} else if (_SLIsEmpty(printer))
RETURN_ERROR(SL_ERR_BAD_PRINTER_NAME);
/*
* Call the appropriate function
*/
if (def_sptr->get_printer_settings_func(printer, settingsp) < 0)
return SL_ERROR;
return SL_NOERROR;
}
/**************************************************************************
*
* Function: SLSysVGetSpoolerOptions
*
* Description: Reads the spooler option settings that have
* been saved by SLSysVSaveSpoolerOptions. The options are
* returned in a format consistent with the System V spooling system.
* Each time this function is called the old contents of the internal
* settings structure becomes invalid. If the caller wishes to
* preserve the old settings information, a copy must be made before
* calling this function.
*
* Note that calling this function does not effect the contents of
* the settings files stored on disk. If a spooler option file is
* not found for the calling user, default settings are returned.
*
* Parameters:
* spooler_optsp (O) - set to a spooler options structure
* filled with the currently saved spooler options
* or default values if no spooler options file
* is found.
*
* Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
* error has occurred. It is considered an error to call this function
* if the System V spooler is not the currently set spooling system.
*
**************************************************************************/
int SLSysVGetSpoolerOptions(SLSysVSpoolerOptionsStruct **spooler_optsp)
{
/*
* In case of error make sure sane values are sent back
*/
*spooler_optsp = NULL;
/*
* Make sure we have the System V spooler set otherwise
* we return an error indication.
*/
CHECK_DEF_SPOOLER;
if (def_sptr->mask != SL_SPOOLER_SYSV)
RETURN_ERROR(SL_ERR_NO_SYSV);
/*
* Call the appropriate function
*/
if (_SLSysVGetSpoolerOptions(spooler_optsp) < 0)
return SL_ERROR;
return SL_NOERROR;
}
/**************************************************************************
*
* Function: SLSysVGetPrinterOptions
*
* Description: Reads the printer specific option settings that have
* been saved by SLSysVSavePrinterOptions. The printer options
* consists of a string of printer specific options that would
* typically be specified on the lp command line using the "-o"
* switch. Each time this function is called the old contents of
* the internal string storage becomes invalid. If the caller wishes to
* preserve the old information, a copy must be made before
* calling this function.
*
* Note that calling this function does not effect the contents of
* the settings files stored on disk. If there are no pritner specific
* settings saved for the specified printer, the options string
* is returned as NULL.
*
* Parameters:
* printer (I) - printer whose options are wanted. If NULL,
* the default printer is used.
* printer_optsp (O) - set to point to a printer specific options
* string or NULL if no printer specific options
* set for this printer or the printer does not
* exist.
*
* Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
* error has occurred. It is considered an error to call this function
* if the System V spooler is not the currently set spooling system.
*
**************************************************************************/
int SLSysVGetPrinterOptions(const char *printer, char **printer_optsp)
{
char *def_printer;
/*
* In case of error make sure sane values are sent back
*/
*printer_optsp = NULL;
/*
* Make sure we have the System V spooler set otherwise
* we return an error indication.
*/
CHECK_DEF_SPOOLER;
if (def_sptr->mask != SL_SPOOLER_SYSV)
RETURN_ERROR(SL_ERR_NO_SYSV);
/*
* Get the default printer name if no printer specified.
* Also sanity check the printer name, if specified.
*/
if (!printer) {
if (SLGetDefPrinterName(&def_printer) < 0)
return SL_ERROR;
printer = def_printer;
} else if (_SLIsEmpty(printer))
RETURN_ERROR(SL_ERR_BAD_PRINTER_NAME);
/*
* Call the appropriate function
*/
if (_SLSysVGetPrinterOptions(printer, printer_optsp) < 0)
return SL_ERROR;
return SL_NOERROR;
}
/**************************************************************************
*
* Function: SLSysVSaveSpoolerOptions
*
* Description: Saves the System V spooler specific options.
*
* Parameters:
* spooler_opts (I) - settings to save.
*
* Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
* error has occurred. It is considered an error to call this function
* if the System V spooler is not the currently set spooling system.
*
**************************************************************************/
int SLSysVSaveSpoolerOptions(SLSysVSpoolerOptionsStruct *spooler_opts)
{
/*
* Make sure we have the System V spooler set otherwise
* we return an error indication.
*/
CHECK_DEF_SPOOLER;
if (def_sptr->mask != SL_SPOOLER_SYSV)
RETURN_ERROR(SL_ERR_NO_SYSV);
/*
* Call the appropriate function
*/
if (_SLSysVSaveSpoolerOptions(spooler_opts) < 0)
return SL_ERROR;
return SL_NOERROR;
}
/**************************************************************************
*
* Function: SLSysVSavePrinterOptions
*
* Description: Saves the System V printer specific option settings.
*
* Parameters:
* printer (I) - printer whose options are to be saved. If NULL,
* the default printer is used.
* printer_opts (I) - options to save.
* location (I) - Save settings for this user (SL_SAVE_USER) or
* for all users (SL_SAVE_DEFAULT). Note that for
* default save to work you must be either 'root'
* or 'lp' according to your current uid.
*
* Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
* error has occurred. It is considered an error to call this function
* if the System V spooler is not the currently set spooling system.
*
**************************************************************************/
int SLSysVSavePrinterOptions(const char *printer,
char *printer_opts, int location)
{
char *def_printer;
/*
* Sanity checks location
*/
if (location != SL_SAVE_USER && location != SL_SAVE_DEFAULT)
location = SL_SAVE_USER;
/*
* Make sure we have the System V spooler set otherwise
* we return an error indication.
*/
CHECK_DEF_SPOOLER;
if (def_sptr->mask != SL_SPOOLER_SYSV)
RETURN_ERROR(SL_ERR_NO_SYSV);
/*
* Get the default printer name if no printer specified.
* Also sanity check the printer name, if specified.
*/
if (!printer) {
if (SLGetDefPrinterName(&def_printer) < 0)
return SL_ERROR;
printer = def_printer;
} else if (_SLIsEmpty(printer))
RETURN_ERROR(SL_ERR_BAD_PRINTER_NAME);
/*
* Call the appropriate function
*/
if (_SLSysVSavePrinterOptions(printer, printer_opts, location) < 0)
return SL_ERROR;
return SL_NOERROR;
}
/**************************************************************************
*
* Function: SLSubmitJob
*
* Description: Submits a job for printing. A print job structure pointer
* is returned that can be used to subsequently cancel or track the
* status of the job. This pointer is reused by this function so users
* wishing to preserve the data in the structure should copy the
* structure.
*
* Parameters:
* filename (I) - file(s) to print. Wildcards acceptable. Multiple
* filenames should be separated by whitespace.
* printer (I) - printer on which to print job. If NULL then default
* printer is used.
* num_copies (I) - number of copies
* copy (I) - Copy flag. If 1 then file is copied to spooling dir. If
* 0 a link is created.
* mail (I) - Mail flag. If 1 then mail is sent on job print completion.
* If 0, no mail is sent.
* title (I) - title to appear on banner page.
* options (I) - string of spooling system/printer specific options.
* Set to NULL if none.
*
* Return: If no error, a pointer to a print job structure is returned. If
* the information in this structure is to be maintained and more jobs
* are to be submitted, this structure should be copied to a user buffer.
* NULL is returned and SLerrno is set if an error has occurred.
*
**************************************************************************/
SLPrintJob* SLSubmitJob(const char *filename, const char *printer,
int num_copies, int copy, int mail,
const char *title, const char *options)
{
SLJobSourceUnion job_source;
SLPrintJob *pjob;
/*
* Perform basic sanity check on the filename
*/
if (!filename || _SLIsEmpty(filename))
RETURN_ERROR_PTR(SL_ERR_NO_FILENAME);
/*
* File out the job source structure
*/
job_source.type = SL_JOB_FILENAME;
job_source.filename_job.filename = filename;
/*
* Call the generic job submittal routine
*/
pjob = submit_job(&job_source, printer, num_copies, copy, mail, title,
options);
return pjob;
}
/**************************************************************************
*
* Function: SLSubmitJobFd
*
* Description: Submits a job for printing. The source for the print job
* is the specified file descriptor. A print job structure pointer
* is returned that can be used to subsequently cancel or track the
* status of the job. This pointer is reused by this function so users
* wishing to preserve the data in the structure should copy the
* structure.
*
* Parameters:
* file_desc (I) - File descriptor of a file open for reading.
* The contents of this file is printed.
* printer (I) - printer on which to print job. If NULL then default
* printer is used.
* num_copies (I) - number of copies
* copy (I) - Copy flag. If 1 then file is copied to spooling dir. If
* 0 a link is created.
* mail (I) - Mail flag. If 1 then mail is sent on job print completion.
* If 0, no mail is sent.
* title (I) - title to appear on banner page.
* options (I) - string of spooling system/printer specific options.
* Set to NULL if none.
*
* Return: If no error, a pointer to a print job structure is returned. If
* the information in this structure is to be maintained and more jobs
* are to be submitted, this structure should be copied to a user buffer.
* NULL is returned and SLerrno is set if an error has occurred.
*
**************************************************************************/
SLPrintJob* SLSubmitJobFd(int file_desc, const char *printer,
int num_copies, int copy, int mail,
const char *title, const char *options)
{
SLJobSourceUnion job_source;
struct stat sbuf;
/*
* Perform basic sanity check on the file descriptor
*/
if (fstat(file_desc, &sbuf) < 0)
RETURN_ERROR_PTR(SL_ERR_BAD_FD);
/*
* File out the job source structure
*/
job_source.type = SL_JOB_FD;
job_source.fd_job.file_desc = file_desc;
/*
* Call the generic job submittal routine
*/
return submit_job(&job_source, printer, num_copies, copy, mail, title,
options);
}
/**************************************************************************
*
* Function: SLSubmitJobBuf
*
* Description: Submits a job for printing. The source for the print job
* is the specified buffer of the specified size (in bytes). A print
* job structure pointer is returned that can be used to subsequently
* cancel or track the status of the job. This pointer is reused by
* this function so users wishing to preserve the data in the structure
* should copy the structure.
*
* Parameters:
* buffer (I) - buffer whose contents are to be printed.
* amount (I) - number of bytes in buffer.
* printer (I) - printer on which to print job. If NULL then default
* printer is used.
* num_copies (I) - number of copies
* copy (I) - Copy flag. If 1 then file is copied to spooling dir. If
* 0 a link is created.
* mail (I) - Mail flag. If 1 then mail is sent on job print completion.
* If 0, no mail is sent.
* title (I) - title to appear on banner page.
* options (I) - string of spooling system/printer specific options.
* Set to NULL if none.
*
* Return: If no error, a pointer to a print job structure is returned. If
* the information in this structure is to be maintained and more jobs
* are to be submitted, this structure should be copied to a user buffer.
* NULL is returned and SLerrno is set if an error has occurred.
*
**************************************************************************/
SLPrintJob* SLSubmitJobBuf(const void *buffer, size_t amount,
const char *printer, int num_copies,
int copy, int mail, const char *title,
const char *options)
{
SLJobSourceUnion job_source;
/*
* Perform basic sanity check on the file descriptor
*/
if (!buffer || !amount)
RETURN_ERROR_PTR(SL_ERR_BAD_BUF);
/*
* File out the job source structure
*/
job_source.type = SL_JOB_BUF;
job_source.buf_job.buffer = buffer;
job_source.buf_job.amount = amount;
/*
* Call the generic job submittal routine
*/
return submit_job(&job_source, printer, num_copies, copy, mail, title,
options);
}
/**************************************************************************
*
* Function: SLSubmitJobSimple
*
* Description: Submits a job for printing. This function provides a
* simple job submittal interface for users who wish to accept
* all defaults. The default printer with the default options
* are used to print the job.
*
* Parameters:
* filename (I) - file(s) to print. Wildcards acceptable. Multiple
* filenames should be separated by whitespace.
*
* Return: If no error, a pointer to a print job structure is returned. If
* the information in this structure is to be maintained and more jobs
* are to be submitted, this structure should be copied to a user buffer.
* NULL is returned and SLerrno is set if an error has occurred.
*
**************************************************************************/
SLPrintJob* SLSubmitJobSimple(const char *filename)
{
/*
* Simply call SLSubmit Job with fields filled in
*/
return SLSubmitJob(filename, NULL, 1, 0, 0, NULL, NULL);
}
/**************************************************************************
*
* Function: SLCancelJob
*
* Description: Makes a request to the specified spooling system to cancel
* the specified job. The following notes apply:
*
* 1. No confirmation that the job was found and canceled is
* provided.
*
* 2. If spooler is SL_SPOOLER_NONE, the current spooling system
* will be used. If a spooler is specified, the job will be
* canceled on that spooling system, but the specified spooling
* system will not become the default spooling system.
*
* 3. For System V print jobs the printer parameter is ignored and
* may be set to NULL. This is because the printer for the job
* is extracted from the job_id.
*
* 4. For BSD print jobs if the printer parameter is NULL, the current
* default printer is assumed.
*
* Parameters:
* job_id (I) - job ID(s) of the print jobs to be canceled. Multiple
* IDs should be separated by whitepsace.
* spooler (I) - print spooler to which job was submitted.
* printer (I) - printer to which job was submitted.
*
* Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
* error has occurred.
*
**************************************************************************/
int SLCancelJob(const char *job_id, unsigned int spooler, const char *printer)
{
register SLSpoolerStruct *sptr;
/*
* Make sure we have a valid spooler selected
*/
CHECK_DEF_SPOOLER;
/*
* Perform basic sanity checks on parameters
*/
if (!job_id || _SLIsEmpty(job_id))
RETURN_ERROR(SL_ERR_NO_JOBID);
/*
* If no spooler specified use the default spooler's
* function. If a spooler is specified, make sure that
* it is valid and call that spooler's cancel function
*/
if (spooler == SL_SPOOLER_NONE)
sptr = def_sptr;
else if (spooler & avail_spoolers)
for (sptr = pos_spooler_list; !(spooler & sptr->mask); sptr++)
;
else
RETURN_ERROR(SL_ERR_SPOOLER_UNKNOWN);
if (sptr->cancel_job_func(job_id, printer) < 0)
return SL_ERROR;
return SL_NOERROR;
}
/**************************************************************************
*
* Function: SLGetSpoolerState
*
* Description: Returns the state of the specified spooling function.
*
* Parameters:
* printer (I) - printer whose spooler state to query. If NULL,
* the default printer is used.
* function (I) - spooling function whose state to query (one of
* SL_PRINTING or SL_QUEUEING).
* statep (O) - state of the spooling function (one of SL_ENABLED or
* SL_DISABLED).
*
* Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
* error has occurred.
*
**************************************************************************/
int SLGetSpoolerState(const char *printer, int function, int *statep)
{
char *def_printer;
/*
* In case of error make sure sane values are sent back
*/
*statep = SL_DISABLED;
/*
* Make sure we have a valid spooler selected
*/
CHECK_DEF_SPOOLER;
/*
* Perform basic sanity checks on the parameters
*/
if (function != SL_PRINTING && function != SL_QUEUEING)
RETURN_ERROR(SL_ERR_BAD_FUNCTION);
/*
* Get the default printer name if no printer specified
* and do some sanity checking if a printer was specified.
*/
if (!printer) {
if (SLGetDefPrinterName(&def_printer) < 0)
return SL_ERROR;
printer = def_printer;
} else if (_SLIsEmpty(printer))
RETURN_ERROR(SL_ERR_BAD_PRINTER_NAME);
/*
* Call the appropriate function
*/
if (def_sptr->get_spooler_state_func(printer, function, statep) < 0)
return SL_ERROR;
return SL_NOERROR;
}
/**************************************************************************
*
* Function: SLSetSpoolerState
*
* Description: Sets the state of the specified spooling function.
* You must have an euid of root to execute this function.
*
* Parameters:
* printer (I) - printer whose spooler state to set. If NULL,
* the default printer is used.
* function (I) - spooling function whose state to set (one of
* SL_PRINTING or SL_QUEUEING).
* state (I) - state to set for the spooling function (one of
* SL_ENABLED or SL_DISABLED).
*
* Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
* error has occurred.
*
**************************************************************************/
int SLSetSpoolerState(const char *printer, int function, int state)
{
char *def_printer;
/*
* Make sure we have a valid spooler selected
*/
CHECK_DEF_SPOOLER;
/*
* Perform basic sanity checks on the parameters
*/
if (function != SL_PRINTING && function != SL_QUEUEING)
RETURN_ERROR(SL_ERR_BAD_FUNCTION);
if (state != SL_ENABLED && state != SL_DISABLED)
RETURN_ERROR(SL_ERR_BAD_STATE);
/*
* Get the default printer name if no printer specified
* and do sanity checking if a printer was specified.
*/
if (!printer) {
if (SLGetDefPrinterName(&def_printer) < 0)
return SL_ERROR;
printer = def_printer;
} else if (_SLIsEmpty(printer))
RETURN_ERROR(SL_ERR_BAD_PRINTER_NAME);
/*
* Call the appropriate function
*/
if (def_sptr->set_spooler_state_func(printer, function, state) < 0)
return SL_ERROR;
return SL_NOERROR;
}
/**************************************************************************
*
* Function: SLGetQueue
*
* Description: Returns the job queue for the specified printer. Note that
* this function requires a printer structure passed as opposed to a
* printer name. This is because the printer structure contains info
* regarding whether the printer is remote and if so, where it is
* located. Note that the any old pointer to the queue will be invalid
* after this call. To save a previous queue the queue structures
* must be copied.
*
* Parameters:
* printer_info (I) - printer structure. Cannot be NULL.
* queue_type (I) - type of queue to obtain (ie. local, remote or
* merged. Ignored for local printers and for
* BSD spooler.
* queuep (O) - print queue entries.
* num_queuep (O) - number of entries in the queue.
*
* Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
* error has occurred.
*
**************************************************************************/
int SLGetQueue(const SLPrinterStruct *printer_info, int queue_type,
SLQueueStruct *queuep[], int *num_queuep)
{
/*
* In case no spooler make sure sane values are sent back
*/
*queuep = NULL;
*num_queuep = 0;
/*
* Make sure we have a valid spooler selected
*/
CHECK_DEF_SPOOLER;
/*
* Perform basic sanity checks on the parameters
*/
if (!printer_info)
RETURN_ERROR(SL_ERR_BAD_PRINTER_STRUCT);
/*
* Call the appropriate function
*/
if (def_sptr->get_queue_func(printer_info, queue_type,
queuep, num_queuep) < 0)
return SL_ERROR;
return SL_NOERROR;
}
/**************************************************************************
*
* Function: SLGetSpoolerError
*
* Description: If SLerrno == SL_ERR_SPOOLER_ERROR this function can
* be called to get the spooler error message(s), if any. This
* function first checks SLerrno to verify that it is set to
* SL_ERR_SPOOLER_ERROR. If it is not, then the function sets
* noutp to 0 and returns. The function returns a list of strings
* which comprise the output from the spooling system and a count
* of the number of lines of output.
*
* Parameters:
* out_bufp (O) - list of strings comprising the output from the
* spooling system.
* noutp (O) - number of lines of output.
*
* Return: Exit status of spooler command that caused the error.
*
**************************************************************************/
int SLGetSpoolerError(char **out_bufp[], int *noutp)
{
/*
* Make sure that last error was a spooler error
*/
if (SLerrno != SL_ERR_SPOOLER_ERROR) {
*noutp = 0;
return 0;
}
/*
* Set parameters to the buffer globals
*/
*out_bufp = _SLspooler_out_buf;
*noutp = _SLspooler_nout;
/*
* Return spooler command exit code
*/
return _SLspooler_exit;
}
#ifdef _SL_FASTPATH
/**************************************************************************
*
* Function: SLBeginFastJob
*
* Description:
* Submit a job to the fast path through the spooling system.
* The idea is that for enormous print jobs, it is very wasteful
* to write all the data to disk, and then have it copied around
* the spooling system, and finally piped to the printer driver.
* Instead, this function in cooperation with the model file for
* the printer sets up a socket so the application can
* communicate directly with the scanner driver, or at least to
* the filters that must be invoked to preprocess the data.
*
* Parameters:
* printer Printer to send data to
* ncopies Number of copies to print
* mail Mail on completion
* title title of job
* options printer specific options
*
* Return: Pointer to a SLFastPrintJob if successful, NULL if error
*
**************************************************************************/
SLFastPrintJob* SLBeginFastJob(const char *printer, int ncopies,
int mail, const char *title, const char *options)
{
int sock;
FASTHEADER header;
SLFastPrintJob *fj = 0;
SLPrintJob *job;
if (!SLSupportsFastJob(printer)) {
RETURN_ERROR_PTR(SL_ERR_NO_FAST_JOB);
}
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
RETURN_ERROR_PTR(SL_ERR_BAD_SOCKET);
}
header.magic = FASTMAGIC;
header.ftype = 0;
header.addrlen = sizeof(header.addr.in);
if (listen(sock, 1) < 0
|| getsockname(sock, &header.addr.in, &header.addrlen) < 0) {
if (SLdebug) {
perror("socket");
}
(void)close(sock);
RETURN_ERROR_PTR(SL_ERR_BAD_SOCKET);
}
job = SLSubmitJobBuf(&header, sizeof(header), printer, ncopies,
1, mail, title, options);
if (job) {
fj = malloc(sizeof(*fj));
fj->job = malloc(sizeof(fj->job));
bcopy(job, fj->job, sizeof(fj->job));
fj->sock = sock;
} else {
(void)close(sock);
}
return fj;
}
/**************************************************************************
*
* Function: SLCancelFastJob
*
* Description:
* Interrupt a fast print job.
*
* Parameters:
* fj The fast job to interrupt
*
* Return: 0 if successful, -1 if error
*
**************************************************************************/
int SLCancelFastJob(SLFastPrintJob *fj)
{
(void)SLCancelJob(fj->job->job_id, fj->job->spooler, fj->job->printer);
(void)SLEndFastJob(fj);
return 0;
}
/**************************************************************************
*
* Function: SLEndFastJob
*
* Description:
* Terminate a fast print job normally. To be called when all
* data has been sent. Frees resources associated with a fast
* print job.
*
* Parameters:
* fj The fast job to terminate
*
* Return: 0 if successful, -1 if error
*
**************************************************************************/
int SLEndFastJob(SLFastPrintJob *fj)
{
(void)close(fj->sock);
free(fj->job);
free(fj);
return 0;
}
/**************************************************************************
*
* Function: SLSupportsFastJob
*
* Description:
* Find out whether a printer supports fast print jobs
*
* Parameters:
* printer printer to find out if supports fast jobs
*
* Return: non-zero if fast job supported, 0 otherwise
*
**************************************************************************/
int
SLSupportsFastJob(const char *printer)
{
CHECK_DEF_SPOOLER;
return def_sptr->supports_fast_job(printer);
}
#endif /* _SL_FASTPATH */
/*
==========================================================================
LOCAL FUNCTIONS
==========================================================================
*/
/**************************************************************************
*
* Function: find_spoolers
*
* Description: Supervises the determination of which print spoolers are
* available. This is based on a determination of whether the spooler's
* scheduler is running.
*
* Parameters:
* spoolersp (O) - bit mask of available spoolers
*
* Return: 0 if success, -1 if error. SLerrno is not set.
*
**************************************************************************/
static int find_spoolers(unsigned int *spoolersp)
{
register SLSpoolerStruct *sptr;
/*
* Based on the list of possible spoolers see which one's
* demon(s) is around.
*/
*spoolersp = SL_SPOOLER_NONE;
for (sptr = pos_spooler_list; sptr->find_spooler_func; sptr++) {
if (sptr->find_spooler_func())
*spoolersp |= sptr->mask;
}
return 0;
}
/**************************************************************************
*
* Function: init_job
*
* Description: Deallocates the storage associated with the members of
* a printer job structure and initializes other fields.
*
* Parameters:
* job (I) - printer job whose storage is to be deallocated.
*
* Return: none
*
**************************************************************************/
static void init_job(SLPrintJob *job)
{
job->spooler = SL_SPOOLER_NONE;
if (job->printer) {
free((char*)job->printer);
job->printer = NULL;
}
if (job->filename) {
free((char*)job->filename);
job->filename = NULL;
}
if (job->username) {
free((char*)job->username);
job->username = NULL;
}
if (job->job_id) {
free((char*)job->job_id);
job->job_id = NULL;
}
}
/**************************************************************************
*
* Function: submit_job
*
* Description: Submits a job for printing. A print job structure pointer
* is returned that can be used to subsequently cancel or track the
* status of the job. This pointer is reused by this function so users
* wishing to preserve the data in the structure should copy the
* structure.
*
* Parameters:
* job_source (I) - the job to print. This is a pointer to the union of
* structures indicating the job source. The first field
* describes the job type (eg. filename, fd, etc.).
* printer (I) - printer on which to print job. If NULL then default
* printer is used.
* num_copies (I) - number of copies
* copy (I) - Copy flag. If 1 then file is copied to spooling dir. If
* 0 a link is created.
* mail (I) - Mail flag. If 1 then mail is sent on job print completion.
* If 0, no mail is sent.
* title (I) - title to appear on banner page.
* options (I) - string of spooling system/printer specific options.
* Set to NULL if none.
*
* Return: If no error, a pointer to a print job structure is returned. If
* the information in this structure is to be maintained and more jobs
* are to be submitted, this structure should be copied to a user buffer.
* NULL is returned and SLerrno is set if an error has occurred.
*
**************************************************************************/
static SLPrintJob* submit_job(SLJobSourceUnion *job_source,
const char *printer, int num_copies, int copy,
int mail, const char *title, const char *options)
{
char *job_id;
char *def_printer;
time_t jtime;
struct tm *jtm;
/*
* Make sure we have a valid spooler selected
*/
CHECK_DEF_SPOOLER_PTR;
/*
* Perform basic sanity checks on the parameters
*/
if (num_copies < 1)
RETURN_ERROR_PTR(SL_ERR_NUM_COPIES);
if (copy != 0 && copy != 1)
RETURN_ERROR_PTR(SL_ERR_JOB_COPY);
if (mail != 0 && mail != 1)
RETURN_ERROR_PTR(SL_ERR_MAIL);
/*
* Initialize the job structure
*/
init_job(&print_job);
/*
* Get the default printer name if no printer specified
*/
if (!printer) {
if (SLGetDefPrinterName(&def_printer) < 0)
return NULL;
printer = def_printer;
} else if (_SLIsEmpty(printer))
RETURN_ERROR_PTR(SL_ERR_BAD_PRINTER_NAME);
/*
* Call the appropriate function
*/
if (def_sptr->submit_job_func(job_source, printer, num_copies,
copy, mail, title, options, &job_id) < 0)
return NULL;
/*
* Fill out the info structure
*/
print_job.spooler = def_spooler;
print_job.printer = strdup(SL_CHAR_CAST(printer));
if (job_source->type == SL_JOB_FILENAME)
print_job.filename =
strdup(SL_CHAR_CAST(job_source->filename_job.filename));
else
print_job.filename = strdup("Standard Input");
print_job.username = strdup(def_sptr->find_username());
print_job.job_id = (job_id) ? strdup(job_id): NULL;
/*
* Put in the time stamp. We zero out the seconds because lpstat
* tends to report job queue time stamps only to the minute
*/
jtime = time((time_t*)NULL);
jtm = localtime(&jtime);
jtm->tm_sec = 0;
print_job.time_stamp = mktime(jtm);
return &print_job;
}
/**************************************************************************
*
* Function: sort_plist
*
* Description: Performs a Shell sort on the printer list to sort the list
* case independently in alphabetical order by local name. The Shell
* sort is used because we will ussually be dealing with very few
* items in the list.
*
* Parameters:
* plist (I,O) - printer list to be sorted
* num (I) - number of printers in the list
*
* Return: none
*
**************************************************************************/
static void sort_plist(SLPrinterStruct *plist, register int num)
{
register int i, j, k, s, *ap;
static int a[] = { 9, 5, 3, 2, 1, 0};
SLPrinterStruct x;
if (!plist || num < 2)
return;
for (ap = a; *ap; ap++) {
k = *ap;
s = -k;
for (i = k; i < num; i++) {
x = plist[i];
j = i - k;
if (!s) {
s = -k;
plist[++s] = x;
}
while (j >= 0 && j < num &&
strcasecmp(x.local_name, plist[j].local_name) < 0) {
plist[j + k] = plist[j];
j -= k;
}
plist[j + k] = x;
}
}
}